package com.huan.iteye.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author huan.fu
 * @date 2017/12/20 - 18:26
 * 日期工具类-用于系统中日期的格式化
 */
@Slf4j
public final class DateUtil {

	private DateUtil() {
	}


	public static LocalTime nowTime() {
		return LocalTime.now();
	}

	public static LocalDate nowDate() {
		return LocalDate.now();
	}

	public static LocalDateTime nowDateTime() {
		return LocalDateTime.now();
	}

	/**
	 * 在给定的时间上减去多少分钟
	 *
	 * @param srcLocalTime 给定的时间
	 * @param minusMinute  需要减去的分钟
	 * @return 减去了给定时间后的时间
	 */
	public static LocalTime minusMinutes(LocalTime srcLocalTime, int minusMinute) {
		return srcLocalTime.minusMinutes(minusMinute);
	}

	/**
	 * 计算出2个时间之间的分钟间隔
	 *
	 * @param srcLocalTime 源时间
	 * @param tarLocalTime 在源时间的基础上减去minusMinute分钟
	 * @param minusMinute  需要减去的分钟数
	 * @param connector    连接符
	 * @return 2个时间之间的间隔
	 */
	public static List<String> sectionMinutes(LocalTime srcLocalTime, LocalTime tarLocalTime, int minusMinute, String connector) {
		int currentHour = srcLocalTime.getHour();
		int currentMinute = srcLocalTime.getMinute();
		int prevHour = tarLocalTime.getHour();
		int prevMinute = tarLocalTime.getMinute();
		log.info("current hour:[{}] current minute:[{}] :{}分钟之前的hour:{} {}分钟之前的minute:[{}]", currentHour, currentMinute, minusMinute, prevHour, minusMinute, prevMinute);
		List<String> ret = new ArrayList<>(minusMinute);
		StringBuilder builder = new StringBuilder();
		if (currentHour > prevHour) {
			for (int i = prevMinute; i < 60; i++) {
				builder.setLength(0);
				builder.append(lessThan10Supplement0(currentHour)).append(connector).append(lessThan10Supplement0(i));
				ret.add(builder.toString());
			}
			for (int i = 0; i < currentMinute; i++) {
				builder.setLength(0);
				builder.append(lessThan10Supplement0(currentHour)).append(connector).append(lessThan10Supplement0(i));
				ret.add(builder.toString());
			}
		} else if (currentHour == prevHour) {
			for (int i = prevMinute; i < currentMinute; i++) {
				builder.setLength(0);
				builder.append(lessThan10Supplement0(currentHour)).append(connector).append(lessThan10Supplement0(i));
				ret.add(builder.toString());
			}
		} else {
			log.error("传递的时间出现问题,默认是减时间");
		}
		return ret;
	}

	public static List<String> sectionMinutes(LocalTime srcLocalTime, int minusMinute, String connector) {
		return sectionMinutes(srcLocalTime, minusMinutes(srcLocalTime, minusMinute), minusMinute, connector);
	}

	public static List<String> sectionMinutes(LocalTime srcLocalTime, int minusMinute) {
		return sectionMinutes(srcLocalTime, minusMinute, ":");
	}

	public static List<String> sectionMinutes(int minusMute) {
		return sectionMinutes(nowTime(), minusMute);
	}

	/**
	 * 返回当前时间和15分钟之前的时间字符串
	 *
	 * @return ["12:01","12:02"]
	 */
	public static List<String> sectionCurrentAndPrev15Minutes() {
		return sectionMinutes(nowTime(), 15);
	}

	/**
	 * 小于10补0
	 *
	 * @param num 需要和10判断的树
	 * @return 进行补0操作
	 */
	public static String lessThan10Supplement0(int num) {
		return num < 10 ? "0" + num : num + "";
	}

	/**
	 * 判断是否是闰年
	 *
	 * @param year
	 * @return
	 */
	public static boolean isLeapYear(int year) {
		return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
	}

	/**
	 * 计算2个时间之间间隔的具体间隔天数
	 *
	 * @param startDate 开始日期
	 * @param endDate   结束日期
	 * @param connector 连接符 -
	 * @return startDate和endDate之间具体的日期range
	 */
	private static List<String> calculateDateRange(List<String> ret, LocalDate startDate, LocalDate endDate, String connector) {
		// startDate比endDate大直接返回
		if (startDate.isAfter(endDate)) {
			return ret;
			// startDate 和 endDate相等
		} else if (startDate.equals(endDate)) {
			ret.add(startDate.format(DateTimeFormatter.ofPattern("yyyy" + connector + "MM" + connector + "dd")));
			return ret;
			// 同年同一个月
		} else if (startDate.getYear() == endDate.getYear() && startDate.getMonthValue() == endDate.getMonthValue()) {
			int startYear = startDate.getYear();
			int startMonth = startDate.getMonthValue();
			int startMonthDay = startDate.getDayOfMonth();
			int startEndMonthDay = endDate.getDayOfMonth();
			StringBuilder builder = new StringBuilder();
			for (int day = startMonthDay; day <= startEndMonthDay; day++) {
				builder.append(startYear).append(connector).append(lessThan10Supplement0(startMonth)).append(connector).append(lessThan10Supplement0(day));
				ret.add(builder.toString());
				builder.setLength(0);
			}
			return ret;
		}
		// 存在跨月的情况
		int startYear = startDate.getYear();
		int startMonth = startDate.getMonthValue();
		int startMonthDay = startDate.getDayOfMonth();
		int startEndMonthDay = startDate.getMonth().length(isLeapYear(startDate.getYear()));
		StringBuilder builder = new StringBuilder();
		for (int day = startMonthDay; day <= startEndMonthDay; day++) {
			builder.append(startYear).append(connector).append(lessThan10Supplement0(startMonth)).append(connector).append(lessThan10Supplement0(day));
			ret.add(builder.toString());
			builder.setLength(0);
		}

		// 如果存在跨月份需要递归进行操作
		if (startDate.plusMonths(1).isBefore(endDate)) {
			LocalDate newStartDate = startDate.plusMonths(1);
			long minusDay = startMonthDay - 1L;
			newStartDate = newStartDate.minusDays(minusDay);
			calculateDateRange(ret, newStartDate, endDate, connector);
		} else {
			int endYear = endDate.getYear();
			int endStartDay = 1;
			int endEndDay = endDate.getDayOfMonth();
			int endMonth = endDate.getMonthValue();
			for (int day = endStartDay; day <= endEndDay; day++) {
				builder.append(endYear).append(connector).append(lessThan10Supplement0(endMonth)).append(connector).append(lessThan10Supplement0(day));
				ret.add(builder.toString());
				builder.setLength(0);
			}
		}

		return ret;
	}

	/**
	 * 计算2个时间之间间隔的具体间隔天数,默认返回的时间格式化yyyy-MM-dd
	 *
	 * @param startDate 开始时间
	 * @param endDate   结束时间
	 * @return startDate和endDate之间具体的日期range
	 */
	public static List<String> calculateDateRange(LocalDate startDate, LocalDate endDate) {
		return calculateDateRange(startDate, endDate, "-");
	}

	/**
	 * 计算2个时间之间间隔的具体间隔天数, 返回的时间格式化connector
	 *
	 * @param startDate 开始时间
	 * @param endDate   结束时间
	 * @return startDate和endDate之间具体的日期range
	 */
	public static List<String> calculateDateRange(LocalDate startDate, LocalDate endDate, String connector) {
		List<String> ret = new ArrayList<>();
		return calculateDateRange(ret, startDate, endDate, connector);
	}

	/**
	 * 格式化日期
	 *
	 * @param date
	 * @param format
	 * @return
	 */
	public static String format(Date date, String format) {
		return new SimpleDateFormat(format).format(date);
	}
}
